﻿using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
namespace Gaea
{
    public static class GaeaExtension
    {
        private static List<IGaeaOption> _temporarygaeaOptionCache;

        /// <summary>
        /// 容器根基根节点
        /// </summary>
        internal static IServiceProvider ServiceProviderRoot { get; private set; }

        private static T GetServiceFromCollection<T>(this IServiceCollection services)
        {
            return (T)services.GetServiceFromCollection(typeof(T));
        }

        private static object GetServiceFromCollection(this IServiceCollection services, Type type)
        {
            return services
                .LastOrDefault(d => d.ServiceType == type)
                ?.ImplementationInstance;
        }

        public static IServiceCollection AddGaeaCore<TDbConnection>(this IServiceCollection serviceCollection, IGaeaAdapter gaeaAdapter, bool isDefault = true, IGaeaOptionCache gaeaOptionCache = null, IGaeaConnectionFactory gaeaConnectionFactory = null) where TDbConnection : DbConnection
        {

            _temporarygaeaOptionCache = new List<IGaeaOption>();
            serviceCollection.AddTransient(typeof(IGaeaAdapter), gaeaAdapter.GetType());
            GaeaSuperPower.SetCommandBuilder(typeof(TDbConnection), gaeaAdapter, isDefault);
            serviceCollection.AddTransient<TDbConnection>();
            if (gaeaOptionCache == null)
            {
                serviceCollection.AddSingleton(typeof(IGaeaOptionCache), typeof(GaeaOptionCache));
            }
            else
            {
                serviceCollection.AddSingleton(typeof(IGaeaOptionCache), gaeaOptionCache.GetType());
            }
            if (gaeaConnectionFactory == null)
            {
                serviceCollection.AddSingleton(typeof(IGaeaConnectionFactory), typeof(GaeaConnectionFactory));
            }
            else
            {
                serviceCollection.AddSingleton(typeof(IGaeaConnectionFactory), gaeaConnectionFactory.GetType());
            }
            return serviceCollection;
        }
        public static IServiceCollection AddGaeaOption(this IServiceCollection serviceCollection, Func<GaeaOption> optionConfiguration)
        {
            _temporarygaeaOptionCache.Add(optionConfiguration.Invoke());
            return serviceCollection;
        }

        public static IServiceProvider UseGaea(this IServiceProvider serviceProvider)
        {

            if (_temporarygaeaOptionCache.Count == 0)
            {
                throw new ArgumentException("Please add gaea option first");
            }
            var gaeaOptionCache = serviceProvider.GetRequiredService<IGaeaOptionCache>();
            _temporarygaeaOptionCache.ForEach(x => gaeaOptionCache.AddOption(x));
            var result = gaeaOptionCache.VerifiactionOption();
            if (!string.IsNullOrWhiteSpace(result))
            {
                throw new ArgumentException(result);
            }
            ServiceProviderRoot = serviceProvider;
            return serviceProvider;
        }


    }
}
